A compiler includes computer software that translates source code in a high-level programming language to a lower level programming language (e.g. machine code) to create binary programs for execution. Just-In-Time (JIT) compilation (dynamic compilation) is a way of executing code that involves compilation at runtime. JIT compilation generally offers better runtime performance because it may be optimized to a target architecture. However, JIT may result in a lag due to compilation. Thus, it is a major challenge for JIT compilers to produce high quality code within a limited compilation time budget.
Instruction scheduling is a classical compiler optimization that is used to improve application runtime performance by reordering an instruction sequence at compile time. Optimization may be performed either before or after register allocation. Performing instruction scheduling before register allocation provides a scheduler more flexibility to hide latencies, but may cause excessive register demand and adversely affect performance due to spill/fill. This is particularly problematic in high memory latency and spill overhead processing architectures in which a compiler has to schedule for maximal latency hiding while keeping register demand low enough to avoid spills.
Traditionally, static compilation may track register demand while scheduling instructions, which typically enables enhanced scheduling, at the cost of compiler software complexity and longer compilation time due to backtracking.